package xyz.labmem.lipx.core.codec

import cn.hutool.core.util.ZipUtil
import cn.hutool.crypto.SecureUtil
import com.alibaba.fastjson2.JSON
import com.alibaba.fastjson2.JSONObject
import io.netty.buffer.ByteBuf
import io.netty.buffer.ByteBufUtil
import io.netty.buffer.Unpooled
import io.netty.channel.ChannelHandlerContext
import io.netty.handler.codec.MessageToMessageDecoder
import xyz.labmem.lipx.core.context.Secret
import xyz.labmem.lipx.core.protocol.LabMessage
import xyz.labmem.lipx.core.protocol.LabMessageType

/**
 * @description: do something
 * @author: ltty
 * @date: 2022/5/30 15:01
 */
class LabMessageDecoder : MessageToMessageDecoder<ByteBuf>() {

    override fun decode(ctx: ChannelHandlerContext, bbf: ByteBuf, out: MutableList<Any>) {
        try {
            //解压
            val gzip = ZipUtil.unGzip(ByteBufUtil.getBytes(bbf))
            val msg = Unpooled.copiedBuffer(gzip)
            val type = msg.readInt()
            val labMessageType = LabMessageType.valueOf(type)
            val readLong = msg.readInt()
            val metaDataBytes = ByteBufUtil.getBytes(msg, 8, readLong)
            val decryptStr = SecureUtil.aes(Secret.getKey()).decryptStr(metaDataBytes)
            val jsonObject :JSONObject?= JSON.parseObject(decryptStr)
            val metaData: Map<String, Any>? = jsonObject?.toMap()
            msg.readBytes(readLong).release()
            var data: ByteArray? = null
            if (msg.isReadable) {
                data = ByteBufUtil.getBytes(msg)
                msg.release()
            }
            out.add(LabMessage().apply {
                this.type = labMessageType
                this.metaData = metaData
                this.data = data
            })
        } catch (e: Exception) {
            bbf.release()
            e.printStackTrace()
        }
    }
}